#Written by MMCOWBOY
import pygame
import sys
import tollgate, enemy
import star, player, collidet
import weapon, msg, gui, effect
import item, mp_attack

import gui


class game_obj:

    LEVEL_LIMIT = 2
    
    def __init__(self, screen, player_num):
        self.screen = screen
        self.screen_size = screen.get_size()
        self.player_num = player_num
        self.is_restart = False
        self.is_continue = False
        pass
        
        self.button_list = []
        self.button_list.append(gui.button2_obj("Restart", pygame.font.Font( "data/Hemi Head 426.TTF", 20 ), 
                           self.restart, (236, 260), (255, 0, 0), (80, 30),None, type))
        self.button_list.append(gui.button2_obj("Continue", pygame.font.Font( "data/Hemi Head 426.TTF", 20 ), 
                           self.resume, (236, 300), (255, 0, 0), (80, 30),None, type))
        self.button_list.append(gui.button2_obj("Exit", pygame.font.Font( "data/Hemi Head 426.TTF", 20 ), 
                            sys.exit, (236, 340), (255, 0, 0), (80, 30),None, type))
    def restart(self):
        self.is_restart = True 

    def resume(self):
        self.is_continue = True

    def run_game(self):
        is_running = True
        
        somebody_alive = True
        
        level = 0
        clock = pygame.time.Clock()
        
        pygame.mixer.music.load("data/sounds/background_music.mp3")
        pygame.mixer.music.set_volume(0.125)
        pygame.mixer.music.play(-1)
        
        #---------------- containers initialize --------------------
        enemys = pygame.sprite.Group()
        stars = pygame.sprite.Group()
        players = pygame.sprite.Group()
        shots = pygame.sprite.Group()
        enemy_shots= pygame.sprite.Group()
        gunfires = pygame.sprite.Group()
        exps = pygame.sprite.Group()
        bomb = pygame.sprite.Group()
        items = pygame.sprite.Group()
        shields = pygame.sprite.Group()
        missile_lunchers = pygame.sprite.Group()
        missile_targets = pygame.sprite.Group()
        missiles = pygame.sprite.Group()
        red_laser_guns = pygame.sprite.Group()
        item_crafts = pygame.sprite.Group()
        shock_waves = pygame.sprite.Group()
        sprites = pygame.sprite.Group()
        bt_lasers = pygame.sprite.Group()
        bt_laser_guns = pygame.sprite.Group()
        world = pygame.sprite.Group()
        
        enemy.enemy_obj.containers = enemys, sprites, missile_targets, world
        star.star_obj.containers = stars, sprites
        player.player_obj.containers = players
        weapon.shot_obj.containers = shots, sprites, world
        weapon.enemy_shot_obj.containers = enemy_shots, sprites, world
        weapon.gun_fire.containers = gunfires, sprites, world
        weapon.bomb_obj.containers = bomb, sprites, world
        weapon.missile_obj.containers = missiles, sprites, world
        effect.flame_spot.containers = exps, sprites, world
        effect.spark_obj.containers = exps, sprites, world
        effect.particle_obj.containers = exps, sprites, world
        item.item_obj.containers = items, sprites, world
        item.shield_obj.containers = shields, world
        item.missile_luncher_obj.containers = missile_lunchers, world
        item.red_laser_gun.containers = red_laser_guns, world
        item.item_craft_obj.containers = item_crafts, missile_targets, world
        effect.shock_wave.containers = shock_waves, world
        mp_attack.bt_laser.containers = bt_lasers, world
        mp_attack.bt_laser_gun.containers = bt_laser_guns, world
        
        
        #------------------------------------------------------------

        
        
        #-------------------- players & gui initialize --------------
        gui_list = []

        for pn in range(self.player_num):
            playergui = gui.user_gui( 'Player%d'%(pn + 1), 0, 0, 0 )
            gui_list.append( playergui )
            if (self.player_num == 1):
                player.player_obj(pn + 1, playergui, self.screen_size, missile_targets, True)
            else:
                player.player_obj(pn + 1, playergui, self.screen_size, missile_targets, False)
        #------------------------------------------------------------

                
                
        #----------------- back ground initialize -------------------
        for i in range(80):
            star.star_obj(self.screen_size)
        #------------------------------------------------------------
        
        #----------------- sounds channels init ---------------------
        
        pygame.mixer.init(22050, -16, 30, 3072)
        pygame.mixer.set_num_channels(100)
        
        
        #------------------------------------------------------------

        while(somebody_alive):
            current_frame = 0              #Current frame counter
            if (level < self.LEVEL_LIMIT):
                level += 1
            else:
                return

            #---------------------------- MAP FILE PROCCESSING ---------------------------------
            # MAP FILE PROCCESSING
            
            cur_mp = tollgate.map_proccessor(self.screen_size, players, str(level) + ".map")

            for g in gui_list:
                g.set_cur_level(cur_mp.get_cur_level())

#            boss_num = cur_mp.get_boss_num()

            #------------------------------------------------------------------------------------

            ending_time = 100
            start_time = 100
            
            message = msg.msgimage("STAGE %s READY" %(cur_mp.get_cur_level()), self.screen.get_rect().center, (248, 221, 28), 40)
            
#            item.item_obj(self.screen_size, (256, 276), item.item_obj.TYPE_SHIELD)
            
#            item.item_obj(self.screen_size, (256, 256), item.item_obj.TYPE_BOMB)
            
            mission_end = False

            while((somebody_alive and not mission_end) or ending_time):
                clock.tick(32)
                
                print clock.get_fps()
                
                for event in pygame.event.get():
                    if (event.type == pygame.QUIT):
                        sys.exit()
                    if (event.type == pygame.KEYDOWN):
                        if (event.key == pygame.K_ESCAPE):
                            is_running = not is_running
                        else:
                            pass

                if (is_running):
                    if (not start_time):
                        current_frame += 1
                    else:
                        start_time -= 1

                    while (1):    #read the object from the map file
                        if (cur_mp.get_available_obj(current_frame / 2) == False):
                            break;
                    
                    self.screen.fill((0,0,0))

#                    players.update()
#                    enemys.update()
#                    stars.update()
#                    shots.update()
#                    gunfires.update()
#                    exps.update()
#                    enemy_shots.update()
#                    bomb.update()
                    
                    players.update()
                    red_laser_guns.update()
                    missile_lunchers.update()
                    sprites.update()
                    shields.update()
                    missiles.update()
                    item_crafts.update()
                    shock_waves.update()
                    bt_laser_guns.update()
                    bt_lasers.update()

                    for s in shields:
                        collidet_enemy = collidet.get_collidet_sg_area(s, enemys, s.rect.width / 2.0)
                        collidet_eshot = collidet.get_collidet_sg_area(s, enemy_shots, s.rect.width / 2.0)
                        collidet_ic = collidet.get_collidet_sg_area(s, item_crafts, s.rect.width / 2.0)
                        if collidet_enemy:
                            for ce in collidet_enemy:
                                s.destroied(ce)
                                ce.destroied(s)
                            
                        if collidet_ic:
                            for ci in collidet_ic:
                                ci.destroied(s)
                            
                        if collidet_eshot:
                            for ceshot in collidet_eshot:
                                s.destroied(ceshot)
                                ceshot.killed()
                            
                            
                    for btl in bt_lasers:
                        collidet_enemy = collidet.get_collidet_sg_laser(btl, enemys)
                        collidet_eshot = collidet.get_collidet_sg_laser(btl, enemy_shots)
                        collidet_ic = collidet.get_collidet_sg_laser(btl, item_crafts)
                        if collidet_enemy:
                            for ce in collidet_enemy:
                                ce.destroied(btl)
                            
                        if collidet_ic:
                            for ci in collidet_ic:
                                ci.destroied(btl)
                            
                        if collidet_eshot:
                            for ceshot in collidet_eshot:
                                ceshot.killed()
                            
                        
                    
                    for b in bomb:
                        if (b.bombed()):
                            collidet_enemy = collidet.get_collidet_sg_area(b, enemys, b.kill_R)
                            collidet_eshot = collidet.get_collidet_sg_area(b, enemy_shots, b.kill_R)
                            collidet_ic = collidet.get_collidet_sg_area(b, item_crafts, b.kill_R)
                            #and collidet_block will be added here...some day - -#
                            for ce in collidet_enemy:
                                ce.destroied(b)
                            
                            for ci in collidet_ic:
                                ci.destroied(b)
                            
                            for ceshot in collidet_eshot:
                                ceshot.killed()
                    
                    for m in missiles:
                        collidet_enemy = collidet.get_collidet_sg(m, enemys)
                        collidet_item_c = collidet.get_collidet_sg(m, item_crafts)
                        if (collidet_enemy):
                            collidet_enemy.destroied(m)
                            m.killed()
                        if (collidet_item_c):
                            collidet_item_c.destroied(m)
                            m.killed()
                        
                    
                    for shot in shots:
                        collidet_enemy = collidet.get_collidet_sg(shot, enemys)
                        collidet_item_c = collidet.get_collidet_sg(shot, item_crafts)
                        if (collidet_enemy):
                            collidet_enemy.destroied(shot)
                            effect.flame_spot(shot.rect.center)
                            #shot flame...
                            shot.killed()
                        if (collidet_item_c):
                            collidet_item_c.destroied(shot)
                            effect.flame_spot(shot.rect.center)
                            #shot flame...
                            shot.killed()
                    
                    for eshot in enemy_shots:
                        collidet_player = collidet.get_collidet_sg(eshot, players)
                        if (collidet_player):
                            if (not collidet_player.is_harm_less() and not collidet_player.is_shield()):
                                collidet_player.destroied(eshot)
                                effect.flame_spot(eshot.rect.center)
                                #shot flame...
                                eshot.killed()
                    
                    for p in players:
                        collidet_enemy = collidet.get_collidet_sg(p, enemys)
                        collidet_item = collidet.get_collidet_sg(p, items)
                        if (collidet_item):
                            if (p.is_alived()):
                                collidet_item.apply(p)
                        if (collidet_enemy):
                            if (p.is_alived() and (not p.is_harm_less())):
                                if (not p.is_shield()):
                                    p.destroied(collidet_enemy)
                                    collidet_enemy.destroied(p)
                                else:
                                    t_shield = p.get_shield()
                                    t_shield.destroied(collidet_enemy)
                                    collidet_enemy.destroied(t_shield)
                        
                    for s in stars:
                        s.draw(self.screen)

                    for e in exps:
                        e.draw(self.screen)
                        
                    for eshot in enemy_shots:
                        eshot.draw(self.screen)

                    for shot in shots:
                        shot.draw(self.screen)

                    for b in bomb:
                        b.draw(self.screen)

                    for e in enemys:
                        e.draw(self.screen)

                    for g in gunfires:
                        g.draw(self.screen)

#                    print len(items)
                        
                    for i in items:
                        i.draw(self.screen)
                        
                    for m in missiles:
                        m.draw(self.screen)
                        
                    for ic in item_crafts:
                        ic.draw(self.screen)
                        
                    for s in shock_waves:
                        s.draw(self.screen)
                        
                    for l in bt_lasers:
                        l.draw(self.screen)
                        
                    for bg in bt_laser_guns:
                        bg.draw(self.screen)
                        
                    for p in players:
                        p.draw(self.screen)
                        
                    for l in red_laser_guns:
                        l.draw(self.screen)
                        
                    for m in missile_lunchers:
                        m.draw(self.screen)
                        
                    for s in shields:
                        s.draw(self.screen)
                        
                    for gl in gui_list:
                        gl.render(self.screen)

                    if (start_time % 4 > 1): #flame spark every 2 flames
                        message.show(self.screen)

                    if (start_time <= 20):
                        message.update("FIGHT")

                    somebody_alive = len(players)
                    
                    mission_end = cur_mp.is_eof() and not len(enemys)
                    
#                    print "l e: ", len(enemys)

                    if (somebody_alive and mission_end):
                        message.update("MISSION COMPLETE")
                        if (ending_time):
                            message.show(self.screen)
                        ending_time -= 1

                    elif (not somebody_alive):
                        message.update("MISSION FAILED")
                        if (ending_time):
                            message.show(self.screen)
                        ending_time -= 1

                    else:
                        pass
                
                else:

                    self.is_restart = False
                    self.is_continue = False

                    for b in self.button_list:
                        b.update()
                    for b in self.button_list:
                        b.draw()
                    
                    if self.is_restart:
                        return 
                    if self.is_continue:
                        is_running = True
                    
                pygame.display.flip()

            for p in players:
                if (p.is_alived()):
                    p.reset_pos()
                    p.recover()
                    
            for p in world:
                p.kill()
